﻿// JScript File

//MzTreeView
function MzTreeView(Tname)
{
  if(typeof(Tname) != "string" || Tname == "")
    throw(new Error(-1, '创建类实例的时候请把类实例的引用变量名传递进来！'));
  
  //【property】
  this.url      = "#";
  this.target   = "_self";
  this.name     = Tname;
  this.currentNode = null;
  this.nodes = {};
  this.node  = {};
  this.names = "";
  this._d    = "\x0f";
  this.divider   = "_";
  this.node["0"] =
  {
    "id": "0",
    "path": "0",
    "isLoad": false,
    "childNodes": [],
    "childAppend": "",
    "sourceIndex": "0"
  };

  this.colors   =
  {
    "highLight" : "#0A246A",
    "highLightText" : "#FFFFFF",
    "mouseOverBgColor" : "#D4D0C8"
  };
  this.icons    = {
    L0        : 'L0.gif',  //┏
    L1        : 'L1.gif',  //┣
    L2        : 'L2.gif',  //┗
    L3        : 'L3.gif',  //━
    L4        : 'L4.gif',  //┃
    PM0       : 'P0.gif',  //＋┏
    PM1       : 'P1.gif',  //＋┣
    PM2       : 'P2.gif',  //＋┗
    PM3       : 'P3.gif',  //＋━
    empty     : 'L5.gif',     //空白图
    root      : 'root.gif',   //缺省的根节点图标
    folder    : 'folder.gif', //缺省的文件夹图标
    file      : 'file.gif',   //缺省的文件图标
    exit      : 'exit.gif'
  };
  this.iconsExpand = {  //存放节点图片在展开时的对应图片
    PM0       : 'M0.gif',     //－┏
    PM1       : 'M1.gif',     //－┣
    PM2       : 'M2.gif',     //－┗
    PM3       : 'M3.gif',     //－━
    folder    : 'folderopen.gif',
    exit      : 'exit.gif'
  };

  //扩展 document.getElementById(id) 多浏览器兼容性
  //id 要查找的对象 id
  this.getElementById = function(id)
  {
    if (typeof(id) != "string" || id == "") return null;
    if (document.getElementById) return document.getElementById(id);
    if (document.all) return document.all(id);
    try {return eval(id);} catch(e){ return null;}
  }

  //MzTreeView 初始化入口函数
  this.toString = function()
  {
    this.browserCheck();
    this.dataFormat();
    this.setStyle();
    this.load("0");
    var rootCN = this.node["0"].childNodes;
    var str = "<A id='"+ this.name +"_RootLink' href='#' style='DISPLAY: none'></A>";
    
    if(rootCN.length>0)
    {
      this.node["0"].hasChild = true;
      for(var i=0; i<rootCN.length; i++)
        str += this.nodeToHTML(rootCN[i], i==rootCN.length-1);
      setTimeout(this.name +".toggle('"+ rootCN[0].id +"'); "+ 
        this.name +".focusClientNode('"+ rootCN[0].id +"'); "+ this.name +".atRootIsEmpty()",10);
    }

    return "<DIV class='MzTreeView' "+
      "onclick='"+ this.name +".clickHandle(event)' "+
      "ondblclick='"+ this.name +".dblClickHandle(event)' "+
      ">"+ str +"</DIV>";
  };
}

//浏览器类型及版本检测
MzTreeView.prototype.browserCheck = function()
{
  var ua = window.navigator.userAgent.toLowerCase(), bname;
  if(/msie/i.test(ua))
  {
    this.navigator = /opera/i.test(ua) ? "opera" : "";
    if(!this.navigator) this.navigator = "msie";
  }
  else if(/gecko/i.test(ua))
  {
    var vendor = window.navigator.vendor.toLowerCase();
    if(vendor == "firefox") this.navigator = "firefox";
    else if(vendor == "netscape") this.navigator = "netscape";
    else if(vendor == "") this.navigator = "mozilla";
  }
  else this.navigator = "msie";
};

//给 TreeView 树加上样式设置
MzTreeView.prototype.setStyle = function()
{
  /*
    width: 16px; \
    height: 16px; \
    width: 20px; \
    height: 20px; \
  */
  var style = "<style>"+
  "DIV.MzTreeView DIV IMG{border: 0px solid #000000;}"+
  "DIV.MzTreeView DIV SPAN IMG{border: 0px solid;}";
  style += "<\/style>";
  document.write(style);
};

//当根节点为空的时候做的处理
MzTreeView.prototype.atRootIsEmpty = function()
{
  var RCN = this.node["0"].childNodes;
  for(var i=0; i<RCN.length; i++)
  {
    if(!RCN[i].isLoad) this.toggle(RCN[i].id);
    if (RCN[i].text=="")
    {
      var node = RCN[i].childNodes[0], HCN  = node.hasChild;
      node.iconExpand  =  RCN[i].childNodes.length>1 ? HCN ? "PM0" : "L0" : HCN ? "PM3" : "L3"
      this.getElementById(this.name +"_expand_"+ node.id).src = this.icons[node.iconExpand].src;
    }
  }
};

//初始化数据源里的数据以便后面的快速检索
MzTreeView.prototype.dataFormat = function()
{
  var a = new Array();
  for (var id in this.nodes) 
  {
    if(this.nodes[id] != null)
      a[a.length] = id;   
  }
  this.names = a.join(this._d + this._d);
  this.totalNode = a.length; a = null;
};

//在数据源检索所需的数据节点
//id  当前客户端节点对应的id
MzTreeView.prototype.load = function(id)
{
  var node = this.node[id], d = this.divider, _d = this._d;
  var sid = node.sourceIndex.substr(node.sourceIndex.indexOf(d) + d.length);  
  var reg = new RegExp("(^|"+_d+")"+ sid +d+"[^"+_d+d +"]+("+_d+"|$)", "g");
  var cns = this.names.match(reg); 
  if (cns){
    reg = new RegExp(_d, "g"); 
    for (var i=0; i<cns.length; i++)
    {
        var childNodeSourceIndex = cns[i].replace(reg, "");
        var childNodeId   = childNodeSourceIndex.substr(childNodeSourceIndex.indexOf(d) + d.length);
        node.childNodes[node.childNodes.length] = this.nodeInit(childNodeId, id); 
    }
  }
  node.isLoad = true;
};

//添加新节点时，为新节点生成一个唯一的id, id用一个模拟的GUID来标识
MzTreeView.prototype.generateGUID = function()
{
    var   guid   =   "";
    for   (var   i   =   1;   i   <=   32;   i++)
    {
      var   n   =   Math.floor(Math.random()   *   16.0).toString(16);
      guid   +=   n;
      if   ((i   ==   8)   ||   (i   ==   12)   ||   (i   ==   16)   ||   (i   ==   20))
        guid   +=   "-";
    }
    return guid;
};

//初始化节点信息, 根据 this.nodes 数据源生成节点的详细信息
//id          当前树节点在客户端的 id
//parentId    当前树节点在客户端的父节点的 id
MzTreeView.prototype.nodeInit = function(id, parentId)
{
  var sourceIndex = parentId + "_" + id;
  var source= this.nodes[sourceIndex], d = this.divider;
  var text  = this.getAttribute(source, "text");
  var hint  = this.getAttribute(source, "hint");
  
  this.node[id] =
  {
    "id"    : id,
    "text"  : text,
    "hint"  : hint ? hint : text,
    "icon"  : this.getAttribute(source, "icon"),
    "path"  : this.node[parentId].path + d + id,
    "isLoad": false,
    "isExpand": false,
    "parentId": parentId,
    "parentNode": this.node[parentId],
    "sourceIndex" : sourceIndex,
    "childAppend" : ""
  };
  source = "id:"+ id +";"+ source;
  this.node[id].hasChild = this.names.indexOf(this._d + id + d)>-1;
  if(this.node[id].hasChild)
    this.node[id].childNodes = [];
  return this.node[id];
};

//从XML格式字符串里提取信息
//source 数据源里的节点信息字符串(以后可以扩展对XML的支持)
//name   要提取的属性名
MzTreeView.prototype.getAttribute = function(source, name)
{
  var reg = new RegExp("(^|;|\\s)"+ name +"\\s*:\\s*([^;]*)(\\s|;|$)", "i");
  if (reg.test(source)) return RegExp.$2.replace(/[\x0f]/g, ";"); return "";
};

//获取当前节点中，存放所有子节点HTML标记的那个Span
MzTreeView.prototype.getChildNodeSpan = function(node)
{
  var nodeSpan = this.getElementById(this.name +"_tree_"+ node.id)
  return nodeSpan.childNodes[nodeSpan.childNodes.length-1];
};

//获取当前节点中，存放所有childAppend图片标记的那个Span
MzTreeView.prototype.getChildAppendSpan = function(node)
{
  return this.getElementById(this.name +"_childAppend_"+ node.id)
};

//根据节点的详细信息生成HTML
//node   树在客户端的节点对象
//AtEnd  布尔值  当前要转换的这个节点是否为父节点的子节点集中的最后一项
MzTreeView.prototype.nodeToHTML = function(node, AtEnd)
{
  var source = this.nodes[node.sourceIndex];
  var target = this.getAttribute(source, "target");
  var data = this.getAttribute(source, "data");
  var url  = this.getAttribute(source, "url");
  if(!url) url = this.url;
  if(data) url += (url.indexOf("?")==-1?"?":"&") + data;
  if(!target) target = this.target;

  var id   = node.id;
  var HCN  = node.hasChild, isRoot = node.parentId=="0";
  if(isRoot)
    node.icon = "root";  
  else
    node.icon = HCN ? "folder" : "file";
  node.iconExpand  = AtEnd ? "└" : "├";

  var HTML = "<DIV noWrap='True'><NOBR>";
  if(!isRoot)
  { 
    node.childAppend = node.parentNode.childAppend + (AtEnd ? "　" : "│");

    node.iconExpand  = HCN ? AtEnd ? "PM2" : "PM1" : AtEnd ? "L2" : "L1";
    HTML += "<SPAN id='" + this.name + "_childAppend_" + id + "'>"+ this.word2image(node.parentNode.childAppend) +"<IMG "+
        "align='absmiddle' id='"+ this.name +"_expand_"+ id +"' "+
        "src='"+ this.icons[node.iconExpand].src +"' style='cursor: "+ (!node.hasChild ? "":
        (this.navigator=="msie"||this.navigator=="opera"? "hand" : "pointer")) +"'></SPAN>";
  }
  HTML += "<IMG "+
    "align='absMiddle' "+
    "id='"+ this.name +"_icon_"+ id +"' "+
    "src='"+ this.icons[node.icon].src +"'><A "+
    "class='MzTreeview' hideFocus "+
    "id='"+ this.name +"_link_"+ id +"' "+
    "href='"+ url +"' "+
    "target='"+ target +"' "+
	//提示
    "title='"+ node.hint +"' "+
    "onfocus=\""+ this.name +".focusLink('"+ id +"')\" "+
    //右键点击节点出现 上下文关联菜单
	"oncontextmenu=\" return "+ this.name +".showcontextmenu(event)\" "+
    "onclick=\"return "+ this.name +".nodeClick('"+ id +"')\">"+ node.text +
  "</A></NOBR></DIV>";
  if(isRoot && node.text=="") HTML = "";
  
  HTML = "\r\n<SPAN id='"+ this.name +"_tree_"+ id +"'>" + HTML;
  HTML += "<SPAN style='DISPLAY: none;'></SPAN></SPAN>";
  return HTML;
};

//在使用图片的时候对 node.childAppend 的转换
MzTreeView.prototype.word2image = function(word)
{
  var str = "";
  for(var i=0; i<word.length; i++)
  {
    var img = "";
    switch (word.charAt(i))
    {
      case "│" : img = "L4"; break;
      case "└" : img = "L2"; break;
      case "　" : img = "empty"; break;
      case "├" : img = "L1"; break;
      case "─" : img = "L3"; break;
      case "┌" : img = "L0"; break;
    }
    if(img!="")
      str += "<IMG align='absMiddle' src='"+ this.icons[img].src +"' height='20'>";
  }
  return str;
}

//获取当前节点在客户端的完整HTML标记
MzTreeView.prototype.getNodeHTML = function(id)
{
    return "\r\n<SPAN id='"+ this.name +"_tree_"+ id +"'>" + this.getElementById(this.name +"_tree_"+ id).innerHTML + "</SPAN>";
};

//将某个节点下的所有子节点转化成详细的<HTML>元素，并显示
//id 树的客户端节点 id
MzTreeView.prototype.buildChildNodesHTML = function(id)
{
  if(this.node[id].hasChild)
  {
    var childNodes = this.node[id].childNodes, str = "";
    for (var i=0; i<childNodes.length; i++)
      str += this.nodeToHTML(childNodes[i], i==childNodes.length-1);   
    this.getChildNodeSpan(this.node[id]).innerHTML = str;
  }
};

//聚集到客户端生成的某个节点上
//id  客户端树节点的id
MzTreeView.prototype.focusClientNode = function(id)
{
  if(!this.currentNode) this.currentNode=this.node["0"];

  var currentLink = this.getElementById(this.name +"_link_"+ id); 
  if(currentLink){ 
    var previousLink = this.getElementById(this.name +"_link_"+ this.currentNode.id);
    if(previousLink) with(previousLink.style){color="";   backgroundColor="";}   
    currentLink.focus();
    with(currentLink.style){color = this.colors.highLightText; backgroundColor = this.colors.highLight;}
    this.currentNode= this.node[id];
  }
};

//焦点聚集到树里的节点链接时的处理
//id 客户端节点 id
MzTreeView.prototype.focusLink = function(id)
{
  if(this.currentNode && this.currentNode.id==id) return;
  this.focusClientNode(id);
};

//节点链接单击事件处理方法
//id 客户端树节点的 id
MzTreeView.prototype.nodeClick = function(id)
{
  var source = this.nodes[this.node[id].sourceIndex];
  eval(this.getAttribute(source, "method"));
  return !(!this.getAttribute(source, "url") && this.url=="#");
};

//为配合系统初始聚集某节点而写的函数, 得到某节点在数据源里的路径
//sourceId 数据源里的节点 id
MzTreeView.prototype.getPath= function(sourceId)
{
  Array.prototype.indexOf = function(item)
  {
    for(var i=0; i<this.length; i++)
    {
      if(this[i]==item) return i;
    }
    return -1;
  };
  var _d = this._d, d = this.divider;
  var A = new Array(), id=sourceId; A[0] = id;
  while(id!="0" && id!="")
  {
    var str = "(^|"+_d+")([^"+_d+d+"]+"+d+ id +")("+_d+"|$)";
    if (new RegExp(str).test(this.names))
    {
      id = RegExp.$2.substring(0, RegExp.$2.indexOf(d));
      if(A.indexOf(id)>-1) break;
      A[A.length] = id;
    }
    else break;
  }
  return A.reverse();
};

//在源代码里指定 MzTreeView 初始聚集到某个节点
//sourceId 节点在数据源里的 id
MzTreeView.prototype.focus = function(sourceId, defer)
{
  if (!defer)
  {
    setTimeout(this.name +".focus('"+ sourceId +"', true)", 100);
    return;
  }
  var path = this.getPath(sourceId);
  if(path[0]!="0")
  {
    alert("节点 "+ sourceId +" 没有正确的挂靠有效树节点上！\r\n"+
      "节点 id 序列 = "+ path.join(this.divider));
    return;
  }
  var root = this.node["0"], len = path.length;
  for(var i=1; i<len; i++)
  {
    if(root.hasChild)
    {
      var sourceIndex= path[i-1] + this.divider + path[i];
      for (var k=0; k<root.childNodes.length; k++)
      {
        if (root.childNodes[k].sourceIndex == sourceIndex)
        {
          root = root.childNodes[k];
          if(i<len - 1) this.toggle(root.id);
          else this.focusClientNode(root.id);
          break;
        }
      }
    }
  }
};

//树的单击事件处理函数
MzTreeView.prototype.clickHandle = function(e)
{
  e = window.event || e; e = e.srcElement || e.target;
  switch(e.tagName)
  {
    case "IMG" :
      if(e.id)
      {
        if(e.id.indexOf(this.name +"_icon_")==0)
          this.focusClientNode(e.id.substr(e.id.lastIndexOf("_") + 1));
        else if (e.id.indexOf(this.name +"_expand_")==0)
          this.toggle(e.id.substr(e.id.lastIndexOf("_") + 1));
      }
      break;
    case "A" :
      if(e.id) this.focusClientNode(e.id.substr(e.id.lastIndexOf("_") + 1));
      break;
    case "SPAN" :
      if(e.className=="pm")
        this.toggle(e.id.substr(e.id.lastIndexOf("_") + 1));
      break;
    default :
      if(this.navigator=="netscape") e = e.parentNode;
      if(e.tagName=="SPAN" && e.className=="pm")
        this.toggle(e.id.substr(e.id.lastIndexOf("_") + 1));
      break;
  }
};

//MzTreeView 双击事件的处理函数
MzTreeView.prototype.dblClickHandle = function(e)
{
  e = window.event || e; e = e.srcElement || e.target;
  if((e.tagName=="A" || e.tagName=="IMG")&& e.id)
  {
    var id = e.id.substr(e.id.lastIndexOf("_") + 1);
    if(this.node[id].hasChild) this.toggle(id);
  }
};

//展开树节点的对应方法
//id 客户端节点 id
MzTreeView.prototype.expand = function(id)
{ 
  var node  = this.node[id];
    
  if (!node.hasChild) return;
  var childNodesSpan = this.getChildNodeSpan(node);
  if (childNodesSpan)
  {
    var icon  = this.icons[node.icon];
    var iconE = this.iconsExpand[node.icon];
    var img   = this.getElementById(this.name +"_icon_"+ id);
    if (img)  img.src = typeof(iconE)=="undefined" ? icon.src : iconE.src;
    var exp   = this.icons[node.iconExpand];
    var expE  = this.iconsExpand[node.iconExpand];
    var expand= this.getElementById(this.name +"_expand_"+ id);
    if (expand)
    {
      expand.src = typeof(expE) =="undefined" ? exp.src  : expE.src;
    }
    
    childNodesSpan.style.display = "block";

    if(!node.isLoad)
    {
      this.load(id);
      if(node.id=="0") return;   //如果是虚拟的根节点，则退出不需要加载
      //当子节点过多时, 给用户一个正在加载的提示语句
      if(node.hasChild && node.childNodes.length>200)
      {
        setTimeout(this.name +".buildChildNodesHTML('"+ id +"')", 1);
        childNodesSpan.innerHTML = "<DIV noWrap><NOBR><SPAN>"+ this.word2image(node.childAppend +"└") +"</SPAN>"+
        "<IMG border='0' height='16' align='absmiddle' src='"+this.icons["file"].src+"'>"+
        "<A style='background-Color: "+ this.colors.highLight +"; color: "+
        this.colors.highLightText +"; font-size: 9pt'>请稍候...</A></NOBR></DIV>";
      }
      else this.buildChildNodesHTML(id);     
    }
  }
};

//折叠树节点的对应方法
//id 客户端节点 id
MzTreeView.prototype.collapse = function(id)
{ 
  var node  = this.node[id];
  if (!node.hasChild) return;
  var childNodesSpan = this.getChildNodeSpan(node);
  if (childNodesSpan)
  {
    var icon  = this.icons[node.icon];
    var iconE = this.iconsExpand[node.icon];
    var img   = this.getElementById(this.name +"_icon_"+ id);
    if (img)  img.src = icon.src;
    var exp   = this.icons[node.iconExpand];
    var expE  = this.iconsExpand[node.iconExpand];
    var expand= this.getElementById(this.name +"_expand_"+ id);
    if (expand)
    {
      expand.src = exp.src;
    }
    if(this.currentNode.path.indexOf(node.path)==0 && this.currentNode.id!=id)
    {
      try{this.getElementById(this.name +"_link_"+ id).click();}
      catch(e){this.focusClientNode(id);}
    }
    childNodesSpan.style.display = "none";
  }
};

//点击展开树节点的对应方法
//id 客户端节点 id
//sureExpand 
MzTreeView.prototype.toggle = function(id,sureExpand)
{ 
  var node  = this.node[id];
  if (!node.hasChild) return;
  var childNodesSpan = this.getChildNodeSpan(node);
  if (childNodesSpan)
  {
    var isCollapse  = sureExpand || childNodesSpan.style.display == "none";
    if(isCollapse)
      this.expand(id);
    else
      this.collapse(id);
  }
};

//展开树的所有节点
MzTreeView.prototype.expandAll = function()
{
  //if(this.totalNode>500) if(
  //  confirm("您是否要停止展开全部节点？\r\n\r\n节点过多！展开很耗时")) return;
  if(this.node["0"].childNodes.length==0) return;
  var e = this.node["0"].childNodes[0];
  var isdo = t = false;
  while(e.id != "0")
  {
    var p = this.node[e.parentId].childNodes, pn = p.length;
    if(p[pn-1].id==e.id && (isdo || !e.hasChild)){e=this.node[e.parentId]; isdo = true;}
    else
    {
      if(e.hasChild && !isdo)
      {
        this.toggle(e.id,true), t = false;
        for(var i=0; i<e.childNodes.length; i++)
        {
          if(e.childNodes[i].hasChild){e = e.childNodes[i]; t = true; break;}
        }
        if(!t) isdo = true;
      }
      else
      {
        isdo = false;
        for(var i=0; i<pn; i++)
        {
          if(p[i].id==e.id) {e = p[i+1]; break;}
        }
      }
    }
  }
};

//折叠树的所有节点
MzTreeView.prototype.collapseAll = function()
{
  if(this.node["0"].childNodes.length==0) return;
  var e = this.node["0"].childNodes[0];
  var isdo = t = false;
  while(e.id != "0")
  {
    var p = this.node[e.parentId].childNodes, pn = p.length;
    if(p[pn-1].id==e.id && (isdo || !e.hasChild)){e=this.node[e.parentId]; isdo = true;}
    else
    {
      if(e.hasChild && !isdo)
      {
        this.collapse(e.id), t = false;
        for(var i=0; i<e.childNodes.length; i++)
        {
          if(e.childNodes[i].hasChild){e = e.childNodes[i]; t = true; break;}
        }
        if(!t) isdo = true;
      }
      else
      {
        isdo = false;
        for(var i=0; i<pn; i++)
        {
          if(p[i].id==e.id) {e = p[i+1]; break;}
        }
      }
    }
  }
};

//判断当前节点是否展开着
MzTreeView.prototype.isNodeExpand = function(node)
{
    if (!node.hasChild) return true;
    var childNodesSpan = this.getChildNodeSpan(node);
    if (childNodesSpan){
      return childNodesSpan.style.display == "block";
    }
    return false;
}

//获取当前节点在其父节点中的位置索引
MzTreeView.prototype.indexOf = function(parentNode, node)
{
    if(parentNode.childNodes == null) return -1;
    for(var i = 0; i < parentNode.childNodes.length; i++)
    {
        if(parentNode.childNodes[i].id == node.id)
        {
            return i;
        }
    }
    return -1;
}

//判断当前节点是否是根结点中的最后一个节点
MzTreeView.prototype.isLastNode = function(node)
{
    if(node.parentNode.childNodes == null) return false;
    var index = this.indexOf(node.parentNode,node);
    if(index == -1) return false;
    return index == node.parentNode.childNodes.length - 1;
}

//获取当前节点子节点的个数，不管当前节点是否已经展开
MzTreeView.prototype.getChildNodeCount = function(parentNode)
{
  var d = this.divider, _d = this._d;
  var sid = parentNode.sourceIndex.substr(parentNode.sourceIndex.indexOf(d) + d.length);  
  var reg = new RegExp("(^|"+_d+")"+ sid +d+"[^"+_d+d +"]+("+_d+"|$)", "g");
  var cns = this.names.match(reg); 
  if (cns){
    return cns.length;
  }
  return 0;
};

//该函数用于更新某个节点的图标以及展开或折叠的图标
MzTreeView.prototype.updateNodeIconAndExpand = function(node, HCN, AtEnd)
{
  if(node == null) return;
  if(node.parentId == "0") return;
  node.icon = HCN ? "folder" : "file";
  node.iconExpand  = HCN ? AtEnd ? "PM2" : "PM1" : AtEnd ? "L2" : "L1";
          
  var icon  = this.icons[node.icon];
  var iconE = this.iconsExpand[node.icon];
  var img   = this.getElementById(this.name +"_icon_"+ node.id);
  if (img)  img.src = typeof(iconE)=="undefined" ? icon.src : iconE.src;
   
  var exp   = this.icons[node.iconExpand];
  var expE  = this.iconsExpand[node.iconExpand];
  var expand= this.getElementById(this.name +"_expand_"+ node.id);
  if (expand)
  {
    expand.src = typeof(expE) =="undefined" ? exp.src  : expE.src;
  }
   
};

//该函数用于更新某个父节点下的所有子节点的childAppend，该函数在添加删除节点时被调用
MzTreeView.prototype.updateChildNodesChildAppend = function(parentNode, childAppendIndex, childAppend, icon)
{
    if(parentNode == null) return;
    if(childAppendIndex < 0) return;
    if(typeof(parentNode.childNodes) == "undefined") return;
    for(var i = 0; i < parentNode.childNodes.length; i++)
    {
        var str = parentNode.childNodes[i].childAppend;
        parentNode.childNodes[i].childAppend = str.substring(0,childAppendIndex) + childAppend + str.substring(childAppendIndex+1);
        var childAppendSpan = this.getChildAppendSpan(parentNode.childNodes[i]);
        var img = childAppendSpan.childNodes[childAppendIndex];
        img.src=this.icons[icon].src;
        this.updateChildNodesChildAppend(parentNode.childNodes[i],childAppendIndex,childAppend,icon);
    }
}

//新增一个叶子节点，注：添加该叶子节点时必须确保其父节点是展开的
MzTreeView.prototype.addNode = function(parentNode, newNodeValue)
{
  if(parentNode == null) return;
  if(parentNode.hasChild && !this.isNodeExpand(parentNode)) return;
  
  var parentNodeId = parentNode.id;
  var newNodeId = this.generateGUID();
  
  this.nodes[parentNodeId + '_' + newNodeId] = newNodeValue;
  this.dataFormat();
  this.nodeInit(newNodeId,parentNodeId);
  
  var childNode = this.node[newNodeId];
  var parentNode = this.node[parentNodeId];
  var newChildNodeHtml = this.nodeToHTML(childNode,true);

  if(typeof(parentNode.childNodes) == "undefined" || parentNode.childNodes.length == 0)
  {
    parentNode.childNodes = [];
    parentNode.hasChild = true;
    parentNode.isLoad = true;
  }
  
  if(parentNode.childNodes.length > 0)
  {
    var previousNode = parentNode.childNodes[parentNode.childNodes.length-1];
    this.updateNodeIconAndExpand(previousNode,previousNode.hasChild,false);
    previousNode.childAppend = previousNode.childAppend.substring(0,previousNode.childAppend.length-1) + "│";
    if(previousNode.childNodes)
    {
      if(parentNode.parentId != "0")
        this.updateChildNodesChildAppend(previousNode,this.getChildAppendSpan(parentNode).childNodes.length,"│", "L4");
      else
        this.updateChildNodesChildAppend(previousNode,0,"│", "L4");
    }
  }
  
  this.updateNodeIconAndExpand(parentNode,true,this.isLastNode(parentNode));
  
  parentNode.childNodes[parentNode.childNodes.length] = childNode;
  
  var childNodesHTML = "";
  for(var i = 0; i < parentNode.childNodes.length - 1; i++)
    childNodesHTML += this.getNodeHTML(parentNode.childNodes[i].id);
            
  childNodesHTML += newChildNodeHtml;
  this.getChildNodeSpan(parentNode).innerHTML = childNodesHTML;
  this.getChildNodeSpan(parentNode).style.display = "block";
};

//删除一个叶子节点，注：删除该叶子节点时必须确保其父节点是展开的
//另外，根节点不能删除
MzTreeView.prototype.removeLeafNode = function(node)
{   
  if(node == null) return;
  if(this.getChildNodeCount(node) > 0)
  {
    alert('当前节点有子节点，不能删除！');
    return;
  }
  if(node.parentId == "0")
  {
    alert('根节点不能删除');  
    return;
  }
  if(node.parentNode.hasChild && !this.isNodeExpand(node.parentNode)) return;
  
  var   d   =   this.divider,   _d   =   this._d   
  var   reg   =   new   RegExp("(^|"+   _d   +")([^"+d+"]+"+d+node.id+")",   "g");   
  var   a   =   this.names.match(reg);  

  if(a == null) return;

  this.names   =   this.names.replace(a[0],"");   
  this.nodes[node.parentId + "_" + node.id] = null;    
  
  if(node.parentNode.isLoad)
  {
    var str = "";
    var childNodes = [];
    var j = 0;
    for(var i = 0; i < node.parentNode.childNodes.length; i++)
    {
        if(node.parentNode.childNodes[i].id != node.id)
        {
            str += this.getNodeHTML(node.parentNode.childNodes[i].id);
            childNodes[j] = node.parentNode.childNodes[i];
            j++;
        }
    }
    node.parentNode.childNodes = childNodes;
    this.getChildNodeSpan(node.parentNode).innerHTML = str;
    if(node.parentNode.childNodes.length == 0)
    {
      this.updateNodeIconAndExpand(node.parentNode,false,this.isLastNode(node.parentNode));
      node.parentNode.hasChild = false;
      this.getChildNodeSpan(node.parentNode).style.display = "none";
    }
    else
    {
      var previousNode = node.parentNode.childNodes[node.parentNode.childNodes.length-1];
      if(this.isNodeExpand(previousNode))
        this.updateNodeIconAndExpand(previousNode,previousNode.hasChild,true);  
      else
      {
        previousNode.iconExpand  = "PM2";
        var exp   = this.icons[previousNode.iconExpand];
        var expand= this.getElementById(this.name +"_expand_"+ previousNode.id);
        if (expand)
        {
          expand.src = exp.src;
        }
      }  
      previousNode.childAppend = previousNode.childAppend.substring(0,previousNode.childAppend.length-1) + "　"; 
      if(previousNode.childNodes)
      {
        if(node.parentNode.parentId != "0")
          this.updateChildNodesChildAppend(previousNode,this.getChildAppendSpan(node.parentNode).childNodes.length,"　", "empty");
        else
          this.updateChildNodesChildAppend(previousNode,0,"　", "empty");          
      }
    }
  
  } 
}

//更新一个节点的文本
MzTreeView.prototype.updateNodeText = function(node, newText)
{
  if(node == null) return;
  if(node.parentNode == null) return;

  this.nodes[node.parentNode.id + '_' + node.id] = this.nodes[node.parentNode.id + '_' + node.id].replace(node.text,newText);
  this.dataFormat();
  node.text = newText;
  this.getElementById(this.name +"_link_"+ node.id).innerHTML = node.text;
};

//本树将要用动的图片的字义及预载函数
//path 图片存放的路径名
MzTreeView.prototype.setIconPath  = function(path)
{
  for(var i in this.icons)
  {
    var tmp = this.icons[i];
    this.icons[i] = new Image();
    this.icons[i].src = path + tmp;
  }
  for(var i in this.iconsExpand)
  {
    var tmp = this.iconsExpand[i];
    this.iconsExpand[i]=new Image();
    this.iconsExpand[i].src = path + tmp;
  }
};

MzTreeView.prototype.setIconFileSrc  = function(imgpath)
{
    this.icons["file"] = new Image();
    this.icons["file"].src = imgpath ;
};
MzTreeView.prototype.setIconFolderSrc  = function(imgpath)
{
    this.icons["folder"] = new Image();
    this.icons["folder"].src = imgpath ;
};
MzTreeView.prototype.setIconExpandFolderSrc  = function(imgpath)
{
    // i - 4 节点文件夹图片在展开时的对应文件夹图片
    this.iconsExpand["folder"]=new Image();
    this.iconsExpand["folder"].src = imgpath;
};

//设置树的默认链接
//url 默认链接  若不设置, 其初始值为 #
MzTreeView.prototype.setURL     = function(url){this.url = url;};

//设置树的默认的目标框架名 target
//target 目标框架名  若不设置, 其初始值为 _self
MzTreeView.prototype.setTarget  = function(target){this.target = target;};

// -->